require 'rubygems'
require 'net/ssh'

class Installr::SSH::SHELL
  def initialize(options={})
    @options = options.dup
    puts "Installr::SSH::SHELL module enabled" if @options[:verbose]
  end

  def open(ip_address, username, password)
    @ssh = Net::SSH.start(ip_address, username, :password => password)
    return 0
    rescue Net::SSH::AuthenticationFailed
      return -2
  end

  def open_with_cert(ip_address, username, key_data, passphrase)
    @ssh = Net::SSH.start(ip_address, username, :key_data => [ key_data ], :passphrase => passphrase)
    return 0
    rescue Net::SSH::AuthenticationFailed
      return -2
  end

  def exec(command)
    exit_code = 0
    output_buffer = []
    ch = @ssh.open_channel do |channel|
      channel.on_request('exit-status') do |ch, data|
        exit_code += data.read_long
      end
      channel.on_request('exit-signal') do |ch, data|
        exit_code += (data.read_long << 8)
      end

      channel.on_data do |ch, data|
        output_buffer << data
      end

      channel.on_extended_data do |ch, type, data|
        output_buffer << data
      end

      channel.request_pty()
      channel.exec(command)
    end

    ch.wait
    output = output_buffer.join('')
    return exit_code, output_buffer.join('')
  end

  def fast_exec(command)
    exit_code = 0
    ch = @ssh.open_channel do |channel|
      channel.on_request('exit-status') do |ch, data|
        exit_code += data.read_long
      end
      channel.on_request('exit-signal') do |ch, data|
        exit_code += (data.read_long << 8)
      end
      channel.request_pty()
      channel.exec(command)
    end
    ch.wait
    return exit_code
  end

  def close
    @ssh.close
  end
end
